/*
*	Copyright(c) 2020 lutianming email：641471957@qq.com
*
*	Sheeps may be copied only under the terms of the GNU Affero General Public License v3.0
*/

#include "common.h"
#include <stdio.h>

#ifdef __WINDOWS__
#include <atlbase.h>
#include <atlconv.h>
#include "iphlpapi.h"
#include <Winsock2.h>
#include <Ws2tcpip.h>
#include <io.h>

#pragma comment(lib, "Iphlpapi.lib")
#else
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>

#endif // __WINDOWS__

int CreateFileDirectory(const char* dir){
	if (NULL == dir) return -1;
	char path[260];
	size_t nPathLen = 0;
#ifdef __WINDOWS__
	strcpy_s(path, sizeof(path), dir);
#else
	strcpy(path, dir);
#endif // __WINDOWS__
	if ((nPathLen = strlen(path)) < 1)
		return -1;
	PathFormat(path);
	for (size_t i = 0; i < nPathLen; ++i){
		if (path[i] == '\\' || path[i] == '/'){
			path[i] = '\0';
			if (ACCESS(path) != 0)
				if (0 != MakeDir(path))
					break;
			path[i] = DIRChar;
		}
	}
	return 0;
}

#ifdef __WINDOWS__
char* GetLocalMacAddr()
{
	PIP_ADAPTER_INFO pAdapterInfo;
	PIP_ADAPTER_INFO pAdapter = NULL;
	DWORD dwRetVal = 0;
	pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
	if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS)
	{
		GlobalFree(pAdapterInfo);
		pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
	}
	if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
	{
		pAdapter = pAdapterInfo;
		while (pAdapter)
		{
			if (
				strstr(pAdapter->Description, "PCI") //pAdapter->Description中包含"PCI"为：物理网卡
				|| pAdapter->Type == 71				//pAdapter->Type是71为：无线网卡
				)
			{
				printf("------------------------------------------------------------\n");
				printf("AdapterName:\t%s\n", pAdapter->AdapterName);
				printf("AdapterDesc:\t%s\n", pAdapter->Description);
				printf("AdapterAddr:\t");
				for (UINT i = 0;i < pAdapter->AddressLength;i++)
				{
					printf("%02X%s", pAdapter->Address[i], i == pAdapter->AddressLength - 1 ? "\n" : "-");
				}
				printf("AdapterType:\t%d\n", pAdapter->Type);
				printf("IPAddress:\t%s\n", pAdapter->IpAddressList.IpAddress.String);
				printf("IPMask:\t%s\n", pAdapter->IpAddressList.IpMask.String);
			}
			pAdapter = pAdapter->Next;
		}
	}
	else
	{
		printf("CalltoGetAdaptersInfofailed.n");
	}
	return NULL;
}
#endif // __WINDOWS__

#define MagicNumber 0x01
#define MagicLowWord 0x02
#define MagicHigWord 0x04
#define MagicSymbol 0x08

int CreateMagicString(unsigned long long code, int flag, unsigned int digits)
{
	static char magic_number[] = "0123456789";
	static char magic_lowword[] = "abcdefghijklmnopqrstuvwxyz";
	static char magic_higword[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	static char magic_symbol[] = "~!@#$%^&*()_+`-=:\"|<>?;',./";

	char magic_sorce[128] = { 0x0 };
	int offset = 0;
	if (flag & MagicNumber)
		offset += snprintf(magic_sorce + offset, sizeof(magic_sorce) - offset, "%s", magic_number);
	if (flag & MagicLowWord)
		offset += snprintf(magic_sorce + offset, sizeof(magic_sorce) - offset, "%s", magic_lowword);
	if (flag & MagicHigWord)
		offset += snprintf(magic_sorce + offset, sizeof(magic_sorce) - offset, "%s", magic_higword);
	if (flag & MagicSymbol)
		offset += snprintf(magic_sorce + offset, sizeof(magic_sorce) - offset, "%s", magic_symbol);

	digits = digits ? digits : offset;
	printf("%d [%s]\n", digits, magic_sorce);

	char out[64] = { 0x0 };
	int pos = 62;
	unsigned long long x = code, y = 0;
	while (1)
	{
		y = x % digits;
		x = x / digits;
		out[pos--] = magic_sorce[y];
		if (x < digits && x > 0)
		{
			out[pos] = magic_sorce[x];
			break;
		}
		else if (x == 0)
		{
			pos++;
			break;
		}
	}
	printf("%s\n", out + pos);
	return 0;
	//CreateMagicString(99 * 65000 * 99, MagicNumber | MagicLowWord | MagicHigWord, 0);
}

static inline bool char_is_blank(int c){
	if (c == 32 || c == 9 || c == 0x0d || c == 0x0a)
		return true;
	return false;
}

static inline int right_blank(char* buf, int len){
	char* p = buf + len - 1;
	while (char_is_blank(*p) && p >= buf){
		*p = 0x0;
		p--;
	}
	return int(p - buf) + 1;
}

static inline int left_blank(char* buf, int len){
	char* p = buf;
	while (char_is_blank(*p) && p < buf + len){
		p++;
	}
	len = len - int(p - buf);
	memmove(buf, p, len);
	*(buf + len) = 0x0;
	return len;
}

int string_trim(char* buf, int len){
	return left_blank(buf, right_blank(buf, len));
}